#include "wxscontainer.h"
#include "wxsitemresdata.h"
#include "wxstool.h"
#include "wxscodercontext.h"
#include <logmanager.h>

wxsContainer::wxsContainer(
  wxsItemResData* Data,
  const wxsItemInfo* Info,
  const wxsEventDesc* EventArray,
  const wxsStyleSet* StyleSet,
  long PropertiesFlags ):
  wxsParent( Data, Info, PropertiesFlags, EventArray, StyleSet ) {
}

bool wxsContainer::OnCanAddChild( wxsItem* Item, bool ShowMessage ) {
  if( Item->GetType() == wxsTSpacer ) {
    if( ShowMessage ) {
      wxMessageBox( _T( "Spacer can be added into sizer only" ) );
    }
    return false;
  }
  if( Item->GetType() == wxsTSizer ) {
    if( GetChildCount() > 0 ) {
      if( GetChild( 0 )->GetType() == wxsTSizer ) {
        if( ShowMessage ) {
          wxMessageBox( _T( "This item can contain only one sizer" ) );
        }
        return false;
      } else {
        if( ShowMessage ) {
          wxMessageBox( _T( "Item can not contain sizer if it has other items inside" ) );
        }
        return false;
      }
    }
    return true;
  }
  if( GetChildCount() > 0 ) {
    if( GetChild( 0 )->GetType() == wxsTSizer ) {
      if( ShowMessage ) {
        wxMessageBox( _T( "Item contains sizer, can not add other items into it." ) );
      }
      return false;
    }
  }
  return true;
}

void wxsContainer::OnEnumItemProperties( long Flags ) {
  OnEnumContainerProperties( Flags );
}

void wxsContainer::OnAddItemQPP( wxsAdvQPP* QPP ) {
  OnAddContainerQPP( QPP );
}

void wxsContainer::AddChildrenPreview( wxWindow* This, long Flags ) {
  for( int i = 0; i < GetChildCount(); i++ ) {
    wxsItem* Child = GetChild( i );
    wxObject* ChildPreviewAsObject = Child->BuildPreview( This, Flags );
    if( Child->GetType() == wxsTSizer ) {
      wxSizer* ChildPreviewAsSizer = wxDynamicCast( ChildPreviewAsObject, wxSizer );
      if( ChildPreviewAsSizer ) {
        This->SetSizer( ChildPreviewAsSizer );
      }
    }
  }
  if( IsRootItem() ) {
    wxsItemResData* Data = GetResourceData();
    if( Data ) {
      for( int i = 0; i < Data->GetToolsCount(); i++ ) {
        Data->GetTool( i )->BuildPreview( This, Flags );
      }
    }
  }
  for( int i = 0; i < GetChildCount(); i++ ) {
    wxsItem* Child = GetChild( i );
    if( Child->GetType() == wxsTSizer ) {
      wxObject* ChildPreviewAsObject = Child->GetLastPreview();
      wxSizer*  ChildPreviewAsSizer  = wxDynamicCast( ChildPreviewAsObject, wxSizer );
      wxWindow* ChildPreviewAsWindow = wxDynamicCast( ChildPreviewAsObject, wxWindow );
      if( ChildPreviewAsSizer ) {
        if( GetBaseProps()->m_Size.IsDefault ) {
          ChildPreviewAsSizer->Fit( This );
        }
        ChildPreviewAsSizer->SetSizeHints( This );
      } else if( ChildPreviewAsWindow ) {
        wxSizer* IndirectSizer = new wxBoxSizer( wxHORIZONTAL );
        IndirectSizer->Add( ChildPreviewAsWindow, 1, wxEXPAND, 0 );
        This->SetSizer( IndirectSizer );
        if( GetBaseProps()->m_Size.IsDefault ) {
          IndirectSizer->Fit( This );
        }
        IndirectSizer->SetSizeHints( This );
      }
    }
  }
}

void wxsContainer::AddChildrenCode() {
  switch( GetLanguage() ) {
    case wxsCPP: {
      wxsCoderContext* Context = GetCoderContext();
      if( !Context ) {
        return;
      }
      wxString PreviousParent = Context->m_WindowParent;
      Context->m_WindowParent = Codef( Context, _T( "%O" ) );
      for( int i = 0; i < GetChildCount(); i++ ) {
        wxsItem* Child = GetChild( i );
        Child->BuildCode( Context );
        if( Child->GetType() == wxsTSizer ) {
          Codef( _T( "%ASetSizer(%o);\n" ), i );
        }
      }
      if( IsRootItem() ) {
        wxsItemResData* Data = GetResourceData();
        if( Data ) {
          for( int i = 0; i < Data->GetToolsCount(); i++ ) {
            Data->GetTool( i )->BuildCode( Context );
          }
        }
      }
      for( int i = 0; i < GetChildCount(); i++ ) {
        wxsItem* Child = GetChild( i );
        if( Child->GetType() == wxsTSizer ) {
          if( GetBaseProps()->m_Size.IsDefault ) {
            wxString ChildAccessPrefix = Child->GetAccessPrefix( GetLanguage() );
            Codef( _T( "%sFit(%O);\n" ), ChildAccessPrefix.wx_str() );
            Codef( _T( "%sSetSizeHints(%O);\n" ), ChildAccessPrefix.wx_str() );
          } else {
            wxString ChildVarName = Child->GetVarName();
            Codef( _T( "SetSizer(%s);\n" ), ChildVarName.wx_str() );
            Codef( _T( "Layout();\n" ) );
          }
        }
      }
      Context->m_WindowParent = PreviousParent;
      return;
    }
    case wxsUnknownLanguage:
    default: {
      wxsCodeMarks::Unknown( _T( "wxsContainer::AddChildrenCode" ), GetLanguage() );
    }
  }
}
